package utils

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"interview/pkg/global"
)

// Struct2JsonString 结构体转为JSON字符串
func Struct2JsonString(obj interface{}) string {
	b, err := json.Marshal(obj)
	if err != nil {
		global.Logger.Debugf("[Struct2JsonString]转换异常: %v", err)
	}
	return string(b)
}

// JsonString2Struct JSON字符串转为结构体
func JsonString2Struct(str string, obj interface{}) {
	err := json.Unmarshal([]byte(str), obj)
	if err != nil {
		global.Logger.Debugf("[JsonString2Struct]转换异常: %v", err)
	}
}

// JsonI2Struct JSON Interface转为结构体
func JsonI2Struct(str interface{}, obj interface{}) {
	jsonStr, _ := str.(string)
	JsonString2Struct(jsonStr, obj)
}

// Struct2StructByJson 结构体转结构体，JSON为中建桥梁，obj2必须传递指针
func Struct2StructByJson(obj1, obj2 interface{}) {
	JsonString2Struct(Struct2JsonString(obj1), obj2)
}

// CompareDifferenceStructByJson 两结构体比对不同的字段, 不同时将取oldStruct中的字段返回, json为中间桥梁, update必须以指针方式传递, 否则可能获取到空数据
func CompareDifferenceStructByJson(oldStruct interface{}, newStruct interface{}, update interface{}) {
	// 通过json先将其转为map集合
	m1 := make(gin.H, 0)
	m2 := make(gin.H, 0)
	m3 := make(gin.H, 0)
	Struct2StructByJson(newStruct, &m1)
	Struct2StructByJson(oldStruct, &m2)

	for k1, v1 := range m1 {
		for k2, v2 := range m2 {
			// key相同, 值不同
			switch v1.(type) {
			case map[string]interface{}:
				continue
			}
			if k1 == k2 && v1 != v2 {
				m3[k1] = v1
				break
			}
		}
	}
	Struct2StructByJson(m3, &update)
}
